package com.letv.core.utils;

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Environment;
import android.os.StatFs;
import android.support.v4.content.ContextCompat;
import android.text.TextUtils;

import com.letv.core.db.PreferencesManager;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class StoreUtils {

    // 默认sd卡大小
    public static final int DEFAULT_SDCARD_SIZE = 1024 * 1024 * 100;

    // Sdcard是否已经挂载，true:挂载;false:卸载
    public static boolean SDCARD_MOUNTED = true;

	public static final String PATH = "Letv/storage/";

    public static final String DOWNLOAD = PATH + "download";

	/**
	 * 将视频添加到下载列表时，保存视频的所有专辑信息。此处为专辑信息的保存目录
	 */
	private static final String DOWNLOAD_EPISODE_INFO = PATH + "download/info";

    private static final String DATAINFO = PATH + "relevant_data";

    private static String SDCARD2_PATH = "/mnt/sdcard2";

    private static String SDCARD_PATH = "/mnt/sdcard";

    private static String SDCARD2_EMULATED ="/storage/sdcard1";

    private static String SDCARD_EX ="/storage/extSdCard";

    private static String SDCARD_EX_BIND = "/mnt/extrasd_bind";

    private static String SDCARD_EXT = "/mnt/sdcard-ext";
    
    public static final String DOWLOAD_LOCATION = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + StoreUtils.DOWNLOAD;


	/**
	 * 删除所有专辑信息。该信息为将视频添加到下载列表时，保存的视频的专辑信息。
	 * 
	 * @param activity
	 */
	public static void clearDownloadEpisodeInfo(Activity activity) {

		File dir = activity.getDir(DOWNLOAD_EPISODE_INFO, Context.MODE_PRIVATE);

		if (dir.exists() && dir.isDirectory()) {
			File[] files = dir.listFiles();

			for (File f : files) {
				f.delete();
			}
		}
	}

	/**
	 * 删除专辑信息。该信息为将视频添加到下载列表时，保存的视频的专辑信息。
	 * 
	 * @param file
	 */
	public static void deleteDownloadEpisodeInfo(final File file) {
		new Thread(new Runnable() {

			@Override
			public void run() {
				if (file != null) {
					file.delete();
				}
			}
		}).start();
	}

    /* =================== 外置Sdcard卡判断和内置手机存储卡判断 Start =================== */

    public static String setDefaultDownloadPath(Context context) {
        String defaultPath = getExternalMemoryPath();
        if (TextUtils.isEmpty(defaultPath)) {
            // 检测外置Sdcard卡是否存在
            defaultPath = getSdcardMemoryPath();
            if (TextUtils.isEmpty(defaultPath)) {
                //解决vivo手机Environment.isExternalStorageRemovable()返回为ture，但是有内置存储问题
                defaultPath = isSdcardAvailable() ? getExternalStorage() : null;
                if (TextUtils.isEmpty(defaultPath)) {
                    // 无存储设备
                    PreferencesManager.getInstance().setDownloadLocation("", false);
                } else {
                    // 内置手机存储卡存在
                    defaultPath += "/" + DOWNLOAD;
                    PreferencesManager.getInstance().setDownloadLocation(defaultPath, true);
                    if (!TextUtils.isEmpty(defaultPath)) {
                        File dir = new File(defaultPath);
                        if (!dir.exists()) {
                            dir.mkdir();
                        }
                    }
                }
            } else {
                // 外置Sdcard卡存在
                defaultPath += "/" + DOWNLOAD;
                if (Build.VERSION.SDK_INT >= 19 && context != null) {
                    defaultPath = StoreUtils.getVer4_4DownloadPath(context);
                }
                
                if (!TextUtils.isEmpty(defaultPath)) {
                    File dir = new File(defaultPath);
                    if (!dir.exists()) {
                        dir.mkdir();
                    }
                }
                
                PreferencesManager.getInstance().setDownloadLocation(defaultPath, false);
            }
        } else {
            // 内置手机存储卡存在
            defaultPath += "/" + DOWNLOAD;
            PreferencesManager.getInstance().setDownloadLocation(defaultPath, true);
            if (!TextUtils.isEmpty(defaultPath)) {
                File dir = new File(defaultPath);
                if (!dir.exists()) {
                    dir.mkdir();
                }
            }
        }

        return defaultPath;
    }

    public static boolean hasExternalMemoryPath() {
        return !TextUtils.isEmpty(getExternalMemoryPath());
    }

    public static boolean hasSdcardMemoryPath() {
        String memPath = getExternalMemoryPath();
        String sdcardPath = getSdcardMemoryPath();
        return !TextUtils.isEmpty(sdcardPath) && !sdcardPath.equalsIgnoreCase(memPath);
    }

    public static String getExternalStorage() {
        File file = null;
        //作保护
        try {
            file = Environment.getExternalStorageDirectory();
        } catch (Exception e) {
            file = null;
        }

        if (null == file) {
            return "";
        } else if (file.exists()) {
            return file.getAbsolutePath();
        } else {
        	return null;
        }
    }
    
    @TargetApi(Build.VERSION_CODES.GINGERBREAD)
    public static String getExternalMemoryPathForSetting() {
        LogInfo.log("ljnalex", "Environment.isExternalStorageRemovable():" + Environment.isExternalStorageRemovable());
        String externalStorageDir = getExternalStorage();
        return ((isSdcardAvailable() && !Environment.isExternalStorageRemovable()) || !TextUtils.isEmpty(externalStorageDir)) ? externalStorageDir : null;
    }

    @TargetApi(Build.VERSION_CODES.GINGERBREAD)
    public static String getExternalMemoryPath() {
        LogInfo.log("ljnalex", "Environment.isExternalStorageRemovable():" + Environment.isExternalStorageRemovable());
        return isSdcardAvailable() && !Environment.isExternalStorageRemovable() ? getExternalStorage() : null;
    }

    @TargetApi(Build.VERSION_CODES.GINGERBREAD)
    public static String getSdcardMemoryPath() {
        if (Build.VERSION.SDK_INT <= 10 && Environment.isExternalStorageRemovable()) {
            if (isSdcardAvailable()) {
                return getExternalStorage();
            } else {
                return null;
            }
        }

        String path = SDCARD2_PATH;
        File file = new File(path);
        if (!file.exists()) {
            path = SDCARD_EX;
            file = new File(path);
            if (!file.exists()) {
                path = SDCARD2_EMULATED;
                file = new File(path);
                if (!file.exists()) {
                    path = SDCARD_EX_BIND;
                    file = new File(path);
                    if (!file.exists()) {
                        path = SDCARD_EXT;
                        file = new File(path);
                        if (!file.exists()) {
                            // 解决手机只有sdcard时，但路径与内置存储相同，识别不出来的问题
                            path = SDCARD_PATH;
                            file = new File(path);
                            if (!file.exists() || !Environment.isExternalStorageRemovable()) {
                                path = null;
                            }
                        }
                    }
                }
            }
        }

        if (file.exists() && (file.getTotalSpace() == 0 || !file.canRead() || !file.canWrite())) {
            path = null;
        }
        
        return path;
    }
    
	public static boolean isSdcardAvailable() {
		boolean exist = Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState());
        LogInfo.log("ljnalex", "Environment.isSdcardAvailable():" + exist);
		return exist;
	}
	
	public static long getAvailableSpaceByPath(String path) {
		if (TextUtils.isEmpty(path)) {
			return -1;
		}
		
		File dir = new File(path);
        if (!dir.exists()) {
            dir.mkdir();
        }
        
        StatFs statFs = null;
        long block = 0;
        long size = 0;
        try {
            statFs = new StatFs(path);
            block = statFs.getAvailableBlocks();
            size = statFs.getBlockSize();
        } catch (Exception e) {
            e.printStackTrace();
        }
		return size * block;
	}

	public static long getSdcardAvailableSpace() {

		if (!isSdcardAvailable()) {

			return -1;
		}
		String sdcardPath = getDownloadDir().getAbsolutePath();
        LogInfo.log("king", "========sdcardPath:" + sdcardPath);
		File dir = new File(sdcardPath);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        StatFs statFs = null;
        long block = 0;
        long size = 0;
        try {
            statFs = new StatFs(sdcardPath);
            block = statFs.getAvailableBlocks();
            size = statFs.getBlockSize();
        } catch (Exception e) {
            LogInfo.log("king", "========e:" + e.getMessage());
            e.printStackTrace();
        }
		return size * block;
	}
	
	/**
	 * 返回当前下载路径
	 * @return
	 */
	public static File getDownloadDir() {
/*		File downloadDir = new File(Environment.getExternalStorageDirectory(),
				PATH_DOWNLOAD);*/
//     /storage/sdcard0/Letv/storage/download
        String path = PreferencesManager.getInstance().getDownloadLocation();
        if (TextUtils.isEmpty(path)) {
            path = DOWLOAD_LOCATION;
        }

		File downloadDir = new File(path);
		if(!downloadDir.exists()){
			downloadDir.mkdirs();
		}

		return downloadDir;
	}
	
	public static long getTotalSpaceByPath(String path) {
		if (TextUtils.isEmpty(path)) {
			return -1;
		}
		
		File dir = new File(path);
        if (!dir.exists()) {
            dir.mkdir();
        }
        
        StatFs statFs = null;
        long block = 0;
        long size = 0;
        try {
        	statFs = new StatFs(path);
			block = statFs.getBlockCount();
			size = statFs.getBlockSize();
        } catch (Exception e) {
            e.printStackTrace();
        }
		return size * block;
	}

	public static long getSdcardTotalSpace() {

		if (!isSdcardAvailable()) {
			return -1;
		}
		String sdcardPath = getDownloadDir().getAbsolutePath();
		File dir = new File(sdcardPath);
		if (!dir.exists()) {
			dir.mkdirs();
		}
		StatFs statFs = null;
		long block = 0;
		long size = 0;
		try {
			statFs = new StatFs(sdcardPath);
			block = statFs.getBlockCount();
			size = statFs.getBlockSize();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return size * block;
	}

	public static File getSdcardRootDirectory() {
		if (isSdcardAvailable()) {
			return Environment.getExternalStorageDirectory();
		}
		return null;
	}

    public static String getVer4_4DownloadPath(Context context) {
        /**
         * ---------------------- Google Declaretion ---------------------
         * Beginning with Android 4.4, however, you can access both locations
         * by calling getExternalFilesDirs(), which returns a File array with
         * entries each location. The first entry in the array is considered
         * the primary external storage and you should use that location unless
         * it's full or unavailable. If you'd like to access both possible locations
         * while also supporting Android 4.3 and lower, use the support library's
         * static method, ContextCompat.getExternalFilesDirs().
         *
         * 4.4kitkat 以上的系统，外置存储卡可写区域只能限制在本apk下
         */
        File[] dirs = ContextCompat.getExternalFilesDirs(context, null);
        LogInfo.log("ljnalex", "dirs.length:" + dirs.length);

        if (dirs == null || dirs.length == 0) {
            return "";
        }

        if (StoreUtils.isSdcardAvailable() && dirs.length >= 2 && dirs[1] != null) {// 存在内置sd卡
            return dirs[1].getAbsolutePath();
        } else if (!StoreUtils.isSdcardAvailable() && dirs[0] != null) {// 不存在内置sd卡
            return dirs[0].getAbsolutePath();
        } else {
            return "";
        }
    }

    /* =================== 外置Sdcard卡判断和内置手机存储卡判断 Start =================== */

	/**
	 * 保存相关数据到文件
	 * 
	 * @param data
	 * @param file
	 */
	private static void writeRelevantData(Context context, final String data, final File file) {
        new AsyncTask<Void, Void, Void>(){
			@Override
			protected Void doInBackground(Void... params) {
				ObjectOutputStream out = null;
                try {
                    out = new ObjectOutputStream(new FileOutputStream(file));
                    out.writeObject(data);
                    out.flush();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    try {
                        if (out != null) {
                            out.close();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                return null;
			}
        }.execute();
	}

	/**
	 * 从文件中读取数据
	 * 
	 * @param file
	 * @return
	 */
	private static String readRelevantData(File file) {
		ObjectInputStream in = null;

		try {
			in = new ObjectInputStream(new FileInputStream(file));
			return (String) in.readObject();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (in != null) {
					in.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		return null;
	}

	public static File getRelevantFile(Context context, String filename) {
		if (!isSdcardAvailable()) {
			return null;
		}

		try {
			File dir = new File(Environment.getExternalStorageDirectory(), DATAINFO);

			if (!dir.isDirectory()) {
				dir.mkdirs();
			}

			File file = new File(dir, filename);

			if (!file.exists()) {
				file.createNewFile();
			}

			return file;
		} catch (IOException e) {
			e.printStackTrace();
		}

		return null;
	}

	public static void saveRelevantData(Context context, String filename, String data) {
		File file = getRelevantFile(context, filename);

		if (file != null && !TextUtils.isEmpty(data)) {
            writeRelevantData(context, data, file);
		}
	}

	public static String getRelevantData(Context context, String filename) {
		File file = getRelevantFile(context, filename);

		if (file != null) {
			return readRelevantData(file);
		}
		return null;
	}
}
